package zero.tech.games.mj.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import zero.tech.games.logic.common.Room;
import zero.tech.games.mj.data.MjGameBase;
import zero.tech.games.mj.data.consts.MjConst;
import zero.tech.games.mj.data.entity.Card;

/**
 * 牌工具
 * @author Administrator
 *
 */
public class CardUtil {
	
	/**
	 * 获取游戏一副牌112张
	 * <li>0,16,32,48 - 万
	 * <li>64,80,96,112 - 条
	 * <li>128,144,160,176 - 同
	 * <li>196,212,228,244 - 红中
	 * @param eightHZ 是否有8个红中
	 * @return
	 */
	public static List<Integer> buildCards112(boolean eightHZ)
	{
		List<Integer> cards = new ArrayList<Integer>();
		for (int i = 0; i < 12; i++){
			//108张
			if(i<12){
				for (int j = 0; j < 9; j++){
					int value = ((byte)i << 4) | (byte)j;
					cards.add(value);
				}
			}
		}
		cards.add(196);
		cards.add(212);
		cards.add(228);
		cards.add(244);
		if(eightHZ) {
			cards.add(196);
			cards.add(212);
			cards.add(228);
			cards.add(244);
		}
		Collections.shuffle(cards);
		return cards;
	}
	
	/**
	 * 获取游戏一副牌108张
	 * <li>0,16,32,48 - 万
	 * <li>64,80,96,112 - 条
	 * <li>128,144,160,176 - 同
	 * @return
	 */
	public static List<Integer> buildCards108()
	{
		List<Integer> cards = new ArrayList<Integer>();
		for (int i = 0; i < 12; i++){
			//当前牌只有108张
			if(i<12){
				for (int j = 0; j < 9; j++){
					int value = ((byte)i << 4) | (byte)j;
					cards.add(value);
				}
			}
		}
		Collections.shuffle(cards);
		return cards;
	}
	
	/**
	 * 是否是鬼牌
	 * @param card 检查的牌
	 * @param guiCards 当局鬼牌
	 * @return
	 */
	public static boolean isGuiPai(int card, List<Integer> guiCards) {
		for (int car : guiCards) {
			if (isSameCard(card, car)) {
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 获取牌打印
	 * @param arr
	 * @return
	 */
	public static String getPai(List<Integer> arr) {
		String str = " ";
		String[] hua = new String[] { "万", "条", "筒", "字" };
		for (Integer integer : arr) {
			int[] car = getCard(integer);
			if (car[3] == 3) {
				if (car[1] == 1)
					str += "东 ";
				else if (car[1] == 2)
					str += "南 ";
				else if (car[1] == 3)
					str += "西 ";
				else if (car[1] == 4)
					str += "北 ";
				else if (car[1] == 5)
					str += "中 ";
				else if (car[1] == 6)
					str += "发 ";
				else if (car[1] == 7)
					str += "白 ";

			} else {
				str += car[1] + hua[car[3]] + " ";
			}
		}

		return str;
	}

	/**
	 * 检测颜色
	 * @param type 类型 0-万，1-条, 2-同
	 * @param color
	 * @return
	 */
	public static boolean checkColor(int type, int color) {
		int[][] lis = new int[4][4];
		lis[0] = new int[] { 0, 16, 32, 48 };
		lis[1] = new int[] { 64, 80, 96, 112 };
		lis[2] = new int[] { 128, 144, 160, 176 };
		lis[3] = new int[] { 192, 208, 224, 240 };
		int[] list = lis[type];
		for (int i = 0; i < list.length; i++) {
			if (list[i] == color) {
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 解析1张牌
	 * @param value
	 * @return [0]花色, [1]点数,[2]原值,[3]类型(0-万，1-条, 2-同)
	 */
	public static int[] getCard(int value) {
		int[] list = new int[4];
		list[0] = value & 0xF0; // 获取花色
		list[1] = (value & 0x0F) + 1; // 获取点数
		list[2] = value; // 牌的原值
		list[3] = getColorType(list[0]); // 牌的原值
		return list;
	}
	
	
	/**
	 * 获取万条同类型
	 * @param color
	 * @return 0-万，1-条, 2-同
	 */
	public static int getColorType(int color) {
		int[][] list = new int[4][4];
		list[0] = new int[] { 0, 16, 32, 48 };
		list[1] = new int[] { 64, 80, 96, 112 };
		list[2] = new int[] { 128, 144, 160, 176 };
		list[3] = new int[] { 192, 208, 224, 240 };
		for (int i = 0; i < list.length; i++) {
			int[] arr = list[i];
			for (int j = 0; j < arr.length; j++) {
				if (arr[j] == color)
					return i;
			}
		}
		return -1;
	}
	
	/**
	 * 检查是否是同一种牌
	 * @param value1
	 * @param value2
	 * @return true 是同一张牌 false 不是
	 */
	public static boolean isSameCard(int value1, int value2) {
		int[] card1 = CardUtil.getCard(value1);
		int[] card2 = CardUtil.getCard(value2);
		if (card1[1] == card2[1] && card1[3] == card2[3]) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 检查是否是鬼牌
	 * @param value1
	 * @param room
	 * @return
	 */
	public static boolean isGuiCard(int value1, Room room) {
		MjGameBase gameBase = (MjGameBase) room.getGameBase();
		List<Integer> guiCards = gameBase.getGuiCards();
		if (guiCards != null && !guiCards.isEmpty()) {
			for (Integer integer : guiCards) {
				if (isSameCard(value1, integer)) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 获取牌点数
	 * @param value
	 * @return
	 */
	public static int getCardValue(int value) {
		int point = (value & 0x0F) + 1; // 获取点数
		return point;
	}

	/**
	 * 获取牌颜色
	 * @param value
	 * @return
	 */
	public static int getCardColor(int value) {
		int point = value & 0xF0; // 获取颜色
		return point;
	}
	
	/**
	 * 获取玩家手中的鬼牌
	 * @param card 手牌
	 * @param gui 公共鬼牌
	 * @return 玩家手中的鬼牌
	 */
	public static List<Integer> getObtainGhost(List<Integer> card, Room room) {
		List<Integer> cards = new ArrayList<Integer>();
		for (int car : card) {
			if (CardUtil.isGuiCard(car, room)) {
				cards.add(car);
			}
		}
		return cards;
	}

	/**
	 * 获取玩家手中的非鬼牌
	 * @param card 手牌
	 * @param gui 公共鬼牌
	 * @return 玩家手中的鬼牌
	 */
	public static List<Integer> getDisObtainGhost(List<Integer> card, Room room) {
		List<Integer> cards = new ArrayList<Integer>();
		for (int car : card) {
			if (!CardUtil.isGuiCard(car, room)) {
				cards.add(car);
			}
		}
		return cards;
	}
	
	/**
	 * 检测碰牌
	 * @param cards
	 * @param tmpArr
	 * @param p_Value
	 * @param len
	 * @return
	 */
	public static boolean checkPengGPai(List<Integer> cards, List<Integer> tmpArr, int p_Value, int len) {
		if (!cards.isEmpty()) {
			int[] arr = CardUtil.getCard(p_Value);
			int type = CardUtil.getColorType(arr[0]);
			for (int i = 0; i < cards.size(); i++) {
				if (cards.get(i) != p_Value) {
					int[] arrTmp = CardUtil.getCard(cards.get(i));
					if (arrTmp[3] == type && arr[1] == arrTmp[1]) {
						tmpArr.add(cards.get(i));
					}
				}
				if (tmpArr.size() == len)
					break;
			}
			if (tmpArr.size() >= len) {
				return true;
			} else {
				tmpArr.clear();
			}
		}
		return false;
	}

	/**
	 * 检测手牌中的暗杠牌
	 * @param cards
	 * @param tmpArr
	 * @param que
	 * @param arr
	 * @param guiCards
	 * @return
	 */
	public static boolean checkGangPai(List<Integer> cards, List<Integer> tmpArr, List<String> arr,List<Integer> guiCards) {
		if (!cards.isEmpty()) {
			int iSize = cards.size();
			if (iSize >= 3) {
				for (int i = 0; i < iSize - 3; i++) {
					int[] p1 = CardUtil.getCard(cards.get(i));
					int[] p2 = CardUtil.getCard(cards.get(i + 1));
					int[] p3 = CardUtil.getCard(cards.get(i + 2));
					int[] p4 = CardUtil.getCard(cards.get(i + 3));
					
					boolean isGui = false;
					for (int j = 0; j < guiCards.size(); j++) {
						int[] gui = CardUtil.getCard(guiCards.get(j));
						if (p1[1] == gui[1] && p1[3] == gui[3]) {
							// 鬼牌不能杠
							isGui = true;
						}
					}

					if (isGui) {
						continue;
					}
					
					if (p1[3] == p2[3] && p2[3] == p3[3] && p3[3] == p4[3]) {
						if (p1[1] == p2[1] && p2[1] == p3[1] && p3[1] == p4[1]) {
							tmpArr.add(cards.get(i));
							tmpArr.add(cards.get(i + 1));
							tmpArr.add(cards.get(i + 2));
							tmpArr.add(cards.get(i + 3));
							// 记录可以杠的牌
							if (arr != null)
								arr.add(MjConst.AN_GANG + "_"
										+ cards.get(i));
						}
					}
				}
			}
			if (tmpArr.size() > 3) {
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 检测明(吧)杠
	 * @param card
	 * @return
	 */
	public static boolean checkMingGang(int card, List<String> arr) {
		for (int i = 0; i < arr.size(); i++) {
			List<String> list = GameUtils.getStrList(arr.get(i), "_");
			if (GameUtils.getInteger(list.get(1)) == MjConst.PENG) {
				List<String> cards = GameUtils.getStrList(list.get(0), ",");
				if (!cards.isEmpty()) {
					int[] p1 = CardUtil.getCard(GameUtils.getInteger(cards
							.get(0)));
					int[] p2 = CardUtil.getCard(card);
					if (p1[3] == p2[3] && p1[1] == p2[1]) {
						return true;
					}
				}
			}
		}
		return false;
	}
	
	/**
	 * 牌排序
	 * @param list
	 * @return
	 */
	public static List<Integer> getNewList(List<Integer> list) {
		List<Integer> arr = new ArrayList<Integer>();
		List<Card> clist = new ArrayList<Card>();
		for (int i = 0; i < list.size(); i++) {
			Card cvo = new Card();
			cvo.setCard(CardUtil.getCard(list.get(i)));
			clist.add(cvo);
		}
		// 处理顺序问题 顺序
		Collections.sort(clist, new Comparator<Card>() {
			public int compare(Card a, Card b) {
				int v = a.getType().compareTo(b.getType());
				if (v == 0) {
					return a.getPoint().compareTo(b.getPoint());
				}
				return v;
			}
		});
		// 重新包装
		for (int i = 0; i < clist.size(); i++) {
			arr.add(clist.get(i).getValue());
		}
		return arr;
	}
	
	/**
	 * 根据配牌id获取牌
	 * @param cardBank 牌库
	 * @param cardIds 配牌id
	 * @param cardNum 获取的牌数量
	 * @return
	 */
	public static List<Integer> findCardsByCardId(List<Integer> cardBank, List<Integer> cardIds, int cardNum) {
		List<Integer> cards = new ArrayList<>();
		for(Integer cardId : cardIds) {
			if(cards.size() < cardNum) {
				cards.add(findCard(cardBank, cardId));
			}
		}
		return cards;
	}

	/**
	 * 查找对应类型对应点数的牌
	 * @param cardBank 牌库
	 * @param cardId 牌id
	 * @return
	 */
	private static Integer findCard(List<Integer> cardBank, Integer cardId) {
		for(Integer card : cardBank) {
			int[] p1 = CardUtil.getCard(card);
			int[] p2 = CardUtil.getCard(cardId);
			if(p1[3] == p2[3] && p1[1] == p2[1]) {
				return card;
			}
		}
		return null;
	}
	
	/**
	 * 删除对应牌库里的牌
	 * @param cardBank 牌库
	 * @param cards 需要删除的牌
	 */
	public static void removeCardBank(List<Integer> cardBank, List<Integer> cards) {
		for (int hcard : cards) {
			for (int i = 0; i < cardBank.size(); i++) {
				if ((int) cardBank.get(i) == hcard) {
					cardBank.remove(i);
				}
			}
		}
	}
	
}
